#include "udpServer.hpp"
#include <memory>
#include <fstream>
#include <unordered_map>
#include <signal.h>
#include <stdio.h>

using namespace std;
using namespace Server;

const std::string dicttxt = "./dict.txt";

static void Usage(string proc)
{
    cout<<"Usage:\n\t"<<proc<<" local_port\n\n";
}

unordered_map<string,string> dict;

static bool curstring(const string&target,string* s1,string*s2,const string &sep)
{
    auto pos = target.find(sep);
    if(pos == string::npos)
    {
        return false;
    }
    *s1 = target.substr(0 , pos);
    *s2 = target.substr(pos + sep.size());
    return true;
}

static void initDict()
{
    ifstream in(dicttxt,std::ios::binary);
    if(!in.is_open())
    {
        std::cerr << "open file "<<dicttxt<<" error"<<std::endl;
        exit(OPEN_ERR);
    }

    string line;
    std::string key,value;

    while(getline(in,line))
    {
        //cout<<line<<endl;
        if(curstring(line,&key,&value,":"))
        {
            dict.insert(make_pair(key,value));
        }
    }

    in.close();

    cout<<"load dict success"<<endl;
}

void reload(int signo)
{
    (void)signo;
    initDict();
}

static void debugprint()
{
    for(auto& dt :dict)
    {
        cout<<dt.first<<" # "<<dt.second<<endl;
    }
}

//demo1
void handerMessage(int sockfd,string clientip,uint16_t clientport,string message)
{
    //就可以对messages进行特殊的业务处理，不用关心怎么来的
    //server通信和业务逻辑解耦

    string response_message;

    auto iter = dict.find(message);
    if(iter == dict.end())
    {
        response_message = "unknow";
    }
    else
    {
        response_message = iter->second;
    }

    //开始返回
    struct sockaddr_in client;
    bzero(&client,sizeof(client));//初始化为全0
    client.sin_family = AF_INET;
    client.sin_port = htons(clientport);
    client.sin_addr.s_addr = inet_addr(clientip.c_str());

    //sleep(10);

    sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&client, sizeof(client));
}

//demo2
void execCommand(int sockfd,string clientip,uint16_t clientport,string cmd)
{
    FILE *fp = popen(cmd.c_str(),"r");

    string response;

    if(fp == nullptr)
    {
        response = "error";
    }

    char line[1024];

    while(fgets(line,sizeof(line),fp))
    {
        response += line;
    }

        //开始返回
    struct sockaddr_in client;
    bzero(&client,sizeof(client));//初始化为全0
    client.sin_family = AF_INET;
    client.sin_port = htons(clientport);
    client.sin_addr.s_addr = inet_addr(clientip.c_str());

    //sleep(10);

    sendto(sockfd, response.c_str(), response.size(), 0, (struct sockaddr *)&client, sizeof(client));

    pclose(fp);
}


int main(int argc,char*argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }

    uint16_t port = atoi(argv[1]);

    //signal(2,reload);
    //initDict();
    //debugprint();

    //std::unique_ptr<udpServer> usvr(new udpServer(handerMessage,port));
    std::unique_ptr<udpServer> usvr(new udpServer(execCommand,port));

    usvr->initServer();
    usvr->start();

    return 0;
}


